package com.channel.modules.system.service.Impl;

import com.channel.modules.system.domain.Dept;
import com.channel.modules.system.service.DataService;
import com.channel.modules.system.service.DeptService;
import com.channel.modules.system.service.RoleService;
import com.channel.modules.system.service.dto.RoleSmallDto;
import com.channel.modules.system.service.dto.UserDto;
import com.commons.utils.enums.DataScopeEnum;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cache.annotation.CacheConfig;
import org.springframework.cache.annotation.Cacheable;
import org.springframework.stereotype.Service;

import java.util.*;

@Service
@CacheConfig(cacheNames = "data")
public class DataServiceImpl implements DataService {

    private final RoleService roleService;
    private final DeptService deptService;

    @Autowired
    public DataServiceImpl(RoleService roleService, DeptService deptService) {
        this.roleService = roleService;
        this.deptService = deptService;
    }


    /**
     * 用户角色和用户部门改变时清理缓存
     * @param user
     * @return
     */
    @Override
    @Cacheable(key = "'user:'+#p0.id")
    public List<Long> getDeptIds(UserDto user) {
        //用于存储部门id
        Set<Long> deptIds=new HashSet<>();
        //查询用户角色
        List<RoleSmallDto> roleSet=roleService.findByUsersId(user.getId());
        //获取对应部门ID
        for(RoleSmallDto role:roleSet){
            DataScopeEnum dataScopeEnum=DataScopeEnum.find(role.getDataScope());
            switch (Objects.requireNonNull(dataScopeEnum)){
                case THIS_LEVEL:
                    deptIds.add(user.getDept().getId());
                    break;
                case CUSTOMIZE:
                    deptIds.addAll(getCustomize(deptIds,role));
                    break;
                default:
                    return new ArrayList<>();
            }
        }
        return new ArrayList<>(deptIds);
    }

    /**
     * 获取自定义的数据权限
     */
    public Set<Long> getCustomize(Set<Long> deptIds, RoleSmallDto role) {
        Set<Dept> depts=deptService.findByRoleId(role.getId());
        for(Dept dept:depts){
            deptIds.add(dept.getId());
            List<Dept> deptChildren=deptService.findByPid(dept.getId());
            if(deptChildren!=null && deptChildren.size()!=0){
                deptIds.addAll(deptService.getDeptChildren(deptChildren));
            }
        }
        return deptIds;
    }
}
